package com.gan.yidademo.stuavatar.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.aliyun.dingtalkyida_1_0.models.SearchFormDatasHeaders;
import com.aliyun.dingtalkyida_1_0.models.SearchFormDatasRequest;
import com.aliyun.dingtalkyida_1_0.models.SearchFormDatasResponse;
import com.aliyun.dingtalkyida_1_0.models.SearchFormDatasResponseBody;
import com.aliyun.tea.TeaException;
import com.aliyun.teautil.models.RuntimeOptions;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gan.yidademo.common.exception.BusinessException;
import com.gan.yidademo.common.util.YiDaUtil;
import com.gan.yidademo.leave.mapper.StuLeaveMapper;
import com.gan.yidademo.leave.model.StuLeave;
import com.gan.yidademo.stuavatar.mapper.StuAvatarMapper;
import com.gan.yidademo.stuavatar.model.StuAvatar;
import com.gan.yidademo.stuavatar.service.StuAvatarService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author gbw
 * @date 2023/9/22
 */
@Slf4j
@Service
public class StuAvatarServiceImpl extends ServiceImpl<StuAvatarMapper, StuAvatar> implements StuAvatarService {

    @Value("${DingDing.ak}")
    private String ak;
    @Value("${DingDing.sk}")
    private String sk;
    /**
     * 应用编码
     */
    @Value("${YiDa.stu_avatar.appType}")
    private String appType;
    /**
     * 应用秘钥
     */
    @Value("${YiDa.stu_avatar.systemToken}")
    private String systemToken;
    /**
     * 用户Id
     */
    @Value("${DingDing.userId}")
    private String userId;
    /**
     * 表单ID
     */
    @Value("${YiDa.stu_avatar.formUuid}")
    private String formUuid;
    /**
     * 图片地址
     */
    @Value("${imgDownLoad}")
    private String imgDownLoad;


    @Override
    public Map<String, Object> getFormData() {
        String token;
        try {
            token = YiDaUtil.getTokenFromApp(ak, sk);
        } catch (Exception e) {
            throw new BusinessException("获取token失败" + e.getMessage());
        }


        com.aliyun.dingtalkyida_1_0.Client client;
        try {
            client = YiDaUtil.createClient();
        } catch (Exception e) {
            throw new BusinessException("创建宜搭客户端失败!");
        }
        Calendar calendar = Calendar.getInstance();
        // 获取过去一周中有变动的数据
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - 7);
        Date today = calendar.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String modifiedFromTimeGMT = format.format(today);

        SearchFormDatasHeaders searchFormDatasHeaders = new SearchFormDatasHeaders();
        searchFormDatasHeaders.xAcsDingtalkAccessToken = token;
        SearchFormDatasRequest searchFormDatasRequest = new SearchFormDatasRequest()
                .setAppType(appType)
                .setSystemToken(systemToken)
                .setUserId(userId)
                .setFormUuid(formUuid)
                .setModifiedFromTimeGMT(modifiedFromTimeGMT);
        try {
            SearchFormDatasResponse stuLeaveResp = client.searchFormDatasWithOptions(searchFormDatasRequest, searchFormDatasHeaders, new RuntimeOptions());
            SearchFormDatasResponseBody body = stuLeaveResp.getBody();
            List<SearchFormDatasResponseBody.SearchFormDatasResponseBodyData> data = body.getData();
            for (SearchFormDatasResponseBody.SearchFormDatasResponseBodyData stu : data) {
                StuAvatar stuAvatar = new StuAvatar();
                String instanceValue = stu.getInstanceValue();
                JSONArray jsonArray = new JSONArray(instanceValue);
                jsonArray.forEach(obj -> {
                    JSONObject jsonObject = (JSONObject) obj;
                    String fieldId = (String) jsonObject.get("fieldId");
                    // 设置字段信息
                    switch (fieldId) {
                        case "ccStudentField_lnwslklg":
                            JSONObject stuData = (JSONObject) jsonObject.get("fieldData");
                            JSONArray stuValueArray = (JSONArray) stuData.get("value");
                            JSONObject stuName = (JSONObject) stuValueArray.get(0);
                            stuAvatar.setStuName((String) stuName.get("text"));
                            break;
                        case "ccClassField_lnwslklj":
                            JSONObject classData = (JSONObject) jsonObject.get("fieldData");
                            JSONArray valueArray = (JSONArray) classData.get("value");
                            JSONObject className = (JSONObject) valueArray.get(0);
                            stuAvatar.setClassName((String) className.get("text"));
                            break;
                        case "employeeField_lnwslkli":
                            JSONObject teacherData = (JSONObject) jsonObject.get("fieldData");
                            JSONArray teaValueArray = (JSONArray) teacherData.get("value");
                            JSONObject teaName = (JSONObject) teaValueArray.get(0);
                            stuAvatar.setHeadTeacher((String) teaName.get("label"));
                            break;
                        case "textField_lnwslkll":
                            JSONObject patriarchIdData = (JSONObject) jsonObject.get("fieldData");
                            String patriarchId = (String) patriarchIdData.get("value");
                            stuAvatar.setPatriarchId(patriarchId);
                            break;
                        case "textField_lnwslklm":
                            JSONObject patriarchNameData = (JSONObject) jsonObject.get("fieldData");
                            String patriarchName = (String) patriarchNameData.get("value");
                            stuAvatar.setPatriarchName(patriarchName);
                            break;
                        case "imageField_lnwslklk":
                            JSONObject avatarData = (JSONObject) jsonObject.get("fieldData");
                            JSONArray avatarArray = (JSONArray) avatarData.get("value");
                            JSONObject avatar = (JSONObject) avatarArray.get(0);
                            String previewUrl = (String) avatar.get("previewUrl");
                            String name = (String) avatar.get("name");
                            File imgSourceFile = new File(imgDownLoad);
                            if (!imgSourceFile.exists()) {
                                try {
                                    imgSourceFile.createNewFile();
                                } catch (IOException e) {
                                    throw new RuntimeException(e);
                                }
                            }
                            // 需要先获取临时免登地址
                            String temporaryExemptionURL = YiDaUtil.getTemporaryExemptionURL(token, userId, previewUrl, systemToken, appType);
                            HttpUtil.downloadFile(temporaryExemptionURL, imgSourceFile);
                            // todo 将学生的头像设置成外网能够访问到的地址
                            stuAvatar.setStuAvatar(imgDownLoad + File.separator + name);
                            break;
                    }
                });
                // 有责更新无责新增，用家长的userId和学生姓名判断
                this.saveOrUpdate(stuAvatar, new UpdateWrapper<StuAvatar>()
                        .eq("patriarch_id", stuAvatar.getPatriarchId())
                        .eq("student_name", stuAvatar.getStuName()));
            }
            return null;
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                log.error("宜搭获取学生头像信息报错 ====== code={}，message={}", err.code, err.message);
            }
            throw new BusinessException(err.getMessage());
        }
    }
}
